package com.lp.controller;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.lp.bo.AliyunParamBO;
import com.lp.bo.IotSceneUserRelationBO;
import com.lp.bo.UserAccountInfoBO;
import com.lp.bo.UserInfoBO;
import com.lp.cache.CacheName;
import com.lp.cache.ProCacheUtil;
import com.lp.cfg.ProConfig;
import com.lp.common.Code;
import com.lp.common.Constants;
import com.lp.common.RequestURL;
import com.lp.common.Code.ResponseCode.UserInfo;
import com.lp.service.UserService;
import com.lp.util.AliyunSmsAndVoiceUtil;
import com.lp.util.CommonUtil;
import com.lp.util.ObjectUtil;
import com.lp.util.ResultMapUtils;
import com.lp.util.yunpianUtil;



@Controller
public class UserController extends BaseController {

	@Autowired
	private UserService userSerivce ;
	
	/**
	 * 用户注册
	 * 
	 * @param req
	 * @param resp
	 * @param user
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURL.User.USER_REGISTER )
	public ModelAndView userRegister(HttpServletRequest req, HttpServletResponse resp,
			@RequestBody UserInfoBO user) {
		Map<String, Object> resultMap = getResultMap();
		try {
			if( ObjectUtil.isNotEmpty(user.getRegister_type()) && user.getRegister_type() == 1 ){
				// 短信携带验证码过来注册
				String register_code =  user.getValidate_code() ;
				String code = ProCacheUtil.getCache(CacheName.USER_SMS, user.getPhone()+"_code");
				if(code.equals(register_code)){
					// 成功
					// 如果是微信公众号内注册，则设置open_id
					user.setWx_open_id( (String) req.getSession().getAttribute("open_id") );
					resultMap = userSerivce.userRegisterByPhone(user);		
				}else{
					// 激活码过去
					putStatusCode(resultMap, Code.ResponseCode.SystemCode.CODE_ERROR);
				}
			}else{
				resultMap = userSerivce.userRegister(user);				
			}
			if(isOk(resultMap)){
				user = (UserInfoBO) getData(resultMap);
				// 注册成功，添加缓存
				ProCacheUtil.addCache(CacheName.USERINFO, user.getUser_key() ,user);
			}
		} catch (Exception e) {
			super.exception(e, resultMap);
		}
		return getModelAndView(resp, resultMap);
	}
	
	/**
	 * 账户验证激活-页面
	 * @param req
	 * @param resp
	 * @param validatecode
	 * @return
	 */
	@RequestMapping(method = RequestMethod.GET, value = RequestURL.User.MAIL_MESSAGE )
	public ModelAndView mailMessage(HttpServletRequest req, HttpServletResponse resp,
			@PathVariable String validatecode) {
		Map<String, Object> resultMap = getResultMap();
		try {
			resultMap = userSerivce.validateCode(validatecode);
		} catch (Exception e) {
			super.exception(e, resultMap);
		}
		return getModelAndView(resp, resultMap,"/oss/iot/message","Info");
	}
	
	/**
	 * 重置密码-页面
	 * @param req
	 * @param resp
	 * @param validatecode
	 * @return
	 */
	@RequestMapping(method = RequestMethod.GET, value = RequestURL.User.MAIL_RESET_PASSWORD_MESSAGE )
	public ModelAndView mailResetPasswordMessage(HttpServletRequest req, HttpServletResponse resp,
			@PathVariable String validatecode) {
		Map<String, Object> resultMap = getResultMap();
		try {
			resultMap = userSerivce.mailValidatePassword(validatecode);
		} catch (Exception e) {
			super.exception(e, resultMap);
		}
		return getModelAndView(resp, resultMap,"/oss/iot/resetpassword","Info");
	}
	
	/**
	 * 重置密码，发送邮件
	 * @param req
	 * @param resp
	 * @param user
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURL.User.RESET_PASSWORD )
	public ModelAndView resetPassword(HttpServletRequest req, HttpServletResponse resp,
			@RequestBody UserInfoBO user) {
		Map<String, Object> resultMap = getResultMap();
		try {
			resultMap = userSerivce.resetPassword(user);
		} catch (Exception e) {
			super.exception(e, resultMap);
		}
		return getModelAndView(resp, resultMap);
	}
	
	/**
	 * 获取账号验证码
	 * 
	 * @param contentType
	 * @param body
	 * @param response
	 * @return
	 */
	@RequestMapping(method = RequestMethod.GET, value = RequestURL.User.VALIDATE_BY_NAME)
	public ModelAndView getSecurityCode(HttpServletResponse response, @PathVariable String name) {
		Map<String, Object> resultMap = getResultMap();
		try {
			resultMap = userSerivce.sendSecurityCode(name);
		} catch (Exception e) {
			super.exception(e, resultMap);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 修改密码
	 * @param req
	 * @param resp
	 * @param user
	 * @return
	 */
	@RequestMapping(method = RequestMethod.PUT, value = RequestURL.User.USER )
	public ModelAndView resetPasswordOver(HttpServletRequest req, HttpServletResponse resp,
			@RequestBody UserInfoBO user) {
		Map<String, Object> resultMap = getResultMap();
		try {
			resultMap = super.service.update("UserInfo.updatePassword", user);
		} catch (Exception e) {
			super.exception(e, resultMap);
		}
		return getModelAndView(resp, resultMap);
	}
	
	
	/**
	 * 修改密码
	 * @param req
	 * @param resp
	 * @param user
	 * @return
	 */
	@RequestMapping(method = RequestMethod.PUT, value = RequestURL.User.USER_MODIFY_PASSWORD )
	public ModelAndView modifyPasswordOver(HttpServletRequest req, HttpServletResponse resp,
			@RequestBody UserInfoBO user) {
		Map<String, Object> resultMap = getResultMap();
		try {
			// 根据id 获取用户信息
			UserInfoBO userCache = ProCacheUtil.getCache(CacheName.USERINFO, user.getUser_key());
			if( userCache.getPassword().equalsIgnoreCase(user.getPassword()) ){
				user.setPassword(user.getNewpassword());
				resultMap = super.service.update("UserInfo.updatePasswordByKey", user);	
				userCache.setPassword(user.getNewpassword());
			}else{
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.PASSWORD_ERROR);
			}
		} catch (Exception e) {
			super.exception(e, resultMap);
		}
		return getModelAndView(resp, resultMap);
	}
	
	/**
	 * 微信公众号信息 绑定
	 * 
	 */
	@RequestMapping(method = RequestMethod.PUT, value = RequestURL.User.WX_USER_BIND )
	public ModelAndView wxBind(HttpServletRequest req, HttpServletResponse resp,
			@RequestBody UserInfoBO user) {
		Map<String, Object> resultMap = getResultMap();
		try {
			if(ObjectUtil.hasNull(user.getName(),user.getPassword(),user.getWx_open_id()  )){
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.PARAM_ERROR);
			}else{
				// ...
				String wxOpenId = user.getWx_open_id();
				user.setWx_open_id(null);
				resultMap = super.service.selectOne("UserInfo.selectOne", user) ;
				if(isOk(resultMap)){
					// 绑定时获取一下session里面的信息
					String wxImg = (String) req.getSession().getAttribute("wximg") ;
					String nickName = (String) req.getSession().getAttribute("nickname") ;
					// 则更新用户信息
					user.setWx_open_id(wxOpenId);
					user.setId( ((UserInfoBO) getData(resultMap)).getId());
					user.setNick_name(nickName);
					user.setWx_img_url(wxImg);
					super.service.update("UserInfo.update", user);
					
					user =  (UserInfoBO) getData(resultMap);
					user.setWx_open_id(wxOpenId);
					req.getSession().setAttribute("user", user);
					// -- 更新缓存
					ProCacheUtil.addCache(CacheName.USERINFO_OPENID, wxOpenId, user);
				}else{
					putStatusCode(resultMap, Code.ResponseCode.UserInfo.USERNAME_OR_PASSWORD_ERROR);
				}
			}
		} catch (Exception e) {
			super.exception(e, resultMap);
		}
		return getModelAndView(resp, resultMap);
	}
	
	/**
	 * 微信小程序 用户绑定
	 * @param req
	 * @param resp
	 * @param user
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURL.User.WP_USER_BIND )
	public ModelAndView userBind(HttpServletRequest req, HttpServletResponse resp,
			@RequestBody UserInfoBO user) {
		Map<String, Object> resultMap = getResultMap();
		try {
			if(ObjectUtil.hasNull(user.getName(),user.getPassword(),user.getWp_id() )){
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.PARAM_ERROR);
			}else{
				// ...
				String wp_id = user.getWp_id();
				user.setWp_id(null);
				resultMap = super.service.selectOne("UserInfo.selectOne", user) ;
				if(isOk(resultMap)){
					// 则更新用户信息
					user.setWp_id(wp_id);
					user.setId( ((UserInfoBO) getData(resultMap)).getId());
					super.service.update("UserInfo.update", user);
				}
			}
		} catch (Exception e) {
			super.exception(e, resultMap);
		}
		return getModelAndView(resp, resultMap);
	}
	/**
	 * 小程序 携带wp_id来获取用户信息
	 * @param req
	 * @param resp
	 * @param user
	 * @return
	 */
	@RequestMapping(method = RequestMethod.GET, value = RequestURL.User.WP_USER_LOGIN )
	public ModelAndView wPUserLogin(HttpServletRequest req, HttpServletResponse resp,
			@RequestParam String code){
		Map<String, Object> resultMap = getResultMap();
		try{
			if( ObjectUtil.isNotEmpty(code) ){
				UserInfoBO userBo = new UserInfoBO();
				userBo.setWp_id(code);
				resultMap = super.service.selectOne("UserInfo.selectOne", userBo) ;
			}else{
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.PARAM_ERROR);
			}
		}catch (Exception e) {
			super.exception(e, resultMap);
		}
		return getModelAndView(resp, resultMap);
	}
	
	/**
	 * 短信登录
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURL.User.USER_SMS_LOGIN )
	public ModelAndView userSmsLogin(HttpServletRequest req, HttpServletResponse resp,
			@RequestBody UserInfoBO user) {
		Map<String, Object> resultMap = getResultMap();
		try {
			if(CommonUtil.isBlank(user.getName()) || CommonUtil.isBlank(user.getValidate_code() )){
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.NO_ACTIVE_CODE);
			}else{
				String register_code =  user.getValidate_code() ;
				String code = ProCacheUtil.getCache(CacheName.USER_SMS, user.getName()+"_code");
				if( code.equals(register_code)){
					UserInfoBO userbo = new UserInfoBO() ;
					userbo.setName(user.getName());
					UserInfoBO userInfo = (UserInfoBO)getData( super.service.selectOne("UserInfo.selectOne", userbo));
					if(ObjectUtil.isNotEmpty(userInfo)){
						if(userInfo.getStatus() == Code.UserStatus.UN_ACTIVED){
							putStatusCode(resultMap, Code.UserStatus.UN_ACTIVED); // 未激活
						}else if(userInfo.getStatus() == Code.UserStatus.FORBIDDEN){
							putStatusCode(resultMap,  Code.UserStatus.FORBIDDEN); // 已禁用
						}else if(userInfo.getStatus() == Code.UserStatus.NORMAL){
							req.getSession().setAttribute("user", userInfo);
							userInfo.setPassword(null);
							putData(resultMap, userInfo);
						}else {
							putStatusCode(resultMap, Code.ResponseCode.SystemCode.NO_ACTIVE_CODE);
						}
					}else{
						putStatusCode(resultMap, Code.ResponseCode.UserInfo.USER_NOT_EXISTS);
					}
				}else {
					putStatusCode(resultMap, Code.ResponseCode.SystemCode.NO_ACTIVE_CODE);
				}
			}
		} catch (Exception e) {
			super.exception(e, resultMap);
		}
		return getModelAndView(resp, resultMap);
	}
	
	/**
	 * 用户登录
	 * 
	 * @param req
	 * @param resp
	 * @param user
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURL.User.USER_LOGIN )
	public ModelAndView userLogin(HttpServletRequest req, HttpServletResponse resp,
			@RequestBody UserInfoBO user) {
		Map<String, Object> resultMap = getResultMap();
		try {
			if(CommonUtil.isBlank(user.getName()) || CommonUtil.isBlank(user.getPassword())){
				putStatusCode(resultMap, Code.ResponseCode.UserInfo.USERNAME_OR_PASSWORD_ERROR);
			}else{
				UserInfoBO userInfo = (UserInfoBO)getData( super.service.selectOne("UserInfo.selectOneLogin", user));
				if(ObjectUtil.isNotEmpty(userInfo)){
					if(userInfo.getStatus() == Code.UserStatus.UN_ACTIVED){
						putStatusCode(resultMap, Code.UserStatus.UN_ACTIVED); // 未激活
					}else if(userInfo.getStatus() == Code.UserStatus.FORBIDDEN){
						putStatusCode(resultMap,  Code.UserStatus.FORBIDDEN); // 已禁用
					}else if(userInfo.getStatus() == Code.UserStatus.NORMAL){
						req.getSession().setAttribute("user", userInfo);
						userInfo.setPassword(null);
						putData(resultMap, userInfo);
					}else {
						putStatusCode(resultMap, Code.ResponseCode.SystemCode.NO_AUTHORIZATION);
					}
				}else{
					putStatusCode(resultMap, Code.ResponseCode.UserInfo.USERNAME_OR_PASSWORD_ERROR);
				}
			}
		} catch (Exception e) {
			super.exception(e, resultMap);
		}
		return getModelAndView(resp, resultMap);
	}
	
	/**
	 * 用户退出
	 * @param req
	 * @param resp
	 * @param user
	 * @return
	 */
	@RequestMapping(method = RequestMethod.GET, value = RequestURL.User.USER_LOGOUT )
	public ModelAndView logout(HttpServletRequest req, HttpServletResponse resp,@RequestParam(required=false) Integer type ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			req.getSession().setAttribute("user", null);
		} catch (Exception e) {
			super.exception(e, resultMap);
		}
		if(type!= null && type == 1){
			return  new ModelAndView("redirect:/service/wiot/login");
		}
		return  new ModelAndView("redirect:/service/iot/login");
	}
	
	/**
	 * 检索用户列表
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURL.User.USER_PAGE)
	public ModelAndView selectUsers(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody UserInfoBO userInfoBO,
			@RequestParam(required=false) Integer pageSize ,
			@RequestParam Integer paged ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			UserInfoBO user = getUserInfoByUserKey(userKey) ;
			if(ObjectUtil.isNotEmpty(user)){
				if(!verifyUserRole(userKey,Code.UserType.SUPER) &&  ObjectUtil.isEmpty(userInfoBO.getAid())  ){
					userInfoBO.setAid(user.getId());
				}
				resultMap = service.selectPageList("UserInfo.select",getPageBean(paged,pageSize), userInfoBO);	
			}else{
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.NO_AUTHORIZATION);
			}
		} catch (Exception e) {
			exception(e,resultMap, userInfoBO);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 修改用户信息
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.PUT, value = RequestURL.User.USER_INFO)
	public ModelAndView update(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody UserInfoBO userInfoBO ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			UserInfoBO user = getUserInfoByUserKey(userKey) ;

			userInfoBO.setMid(user.getId());
			resultMap = super.service.update("UserInfo.update", userInfoBO);
			if(isOk(resultMap)){
				ProCacheUtil.addCache(CacheName.USERINFO, userInfoBO.getUser_key() ,userInfoBO);
			}
		} catch (Exception e) {
			exception(e,resultMap, userInfoBO);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 修改当前用户信息
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.PUT, value = RequestURL.User.USER_INFO_MODIFY)
	public ModelAndView updateSelf(HttpServletResponse response, HttpServletRequest req ,
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody UserInfoBO userInfoBO ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			UserInfoBO user = getUserInfoByUserKey(userKey) ;
			userInfoBO.setId(user.getId());
			resultMap = super.service.update("UserInfo.update", userInfoBO);
			if(isOk(resultMap)){
				UserInfoBO userInfo = getUserInfoBySession(req);
				userInfo.setPhone(userInfoBO.getPhone());
				userInfo.setEmail(userInfoBO.getEmail());
				userInfo.setNick_name(userInfoBO.getNick_name());
				req.getSession().setAttribute("user", userInfo);
			}
		} catch (Exception e) {
			exception(e,resultMap, userInfoBO);
		}
		return getModelAndView(response, resultMap);
	}
	/**
	 * 增加用户
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURL.User.USER_INFO)
	public ModelAndView add(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody UserInfoBO userInfoBO ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			// 这边需要处理，不允许用户名、邮箱和手机号重复
			UserInfoBO userInfo = new UserInfoBO();
			userInfo.setName(userInfoBO.getName());
			if( service.count("UserInfo.selectCount", userInfo) >0){
				// 用户名重复
				putStatusCode(resultMap, Code.ResponseCode.UserInfo.NAME_EXIST);
			}else{
				userInfo.setName(null);
				userInfo.setEmail(userInfoBO.getEmail());
				if( service.count("UserInfo.selectCount", userInfo) >0 ){
					// 邮箱重复
					putStatusCode(resultMap, Code.ResponseCode.UserInfo.EMAIL_EXIST);
				}else{
					userInfo.setPhone(userInfoBO.getPhone());
					userInfo.setEmail(null);
					if(service.count("UserInfo.selectCount", userInfo) >0){
						// 电话号码重复
						putStatusCode(resultMap, Code.ResponseCode.UserInfo.PHONE_EXIST);
					}					
				}
			}
			if(isOk(resultMap)){
				userInfoBO.setAid(getUserInfoByUserKey(userKey).getId());
				userInfoBO.setUser_key(CommonUtil.UUIDString.getUUIDString());
				userInfoBO.setRegister_time(new Date());
				userInfoBO.setStatus(Code.UserStatus.NORMAL);
				resultMap = super.service.insert("UserInfo.insert", userInfoBO);
				if(isOk(resultMap)){
					ProCacheUtil.addCache(CacheName.USERINFO, userInfoBO.getUser_key() ,userInfoBO);
					/**
					 * 添加用户的账户表
					 */
					UserAccountInfoBO userAccountBo = new UserAccountInfoBO();
					userAccountBo.setUser_id(userInfoBO.getId());
					resultMap = super.service.insert("UserAccountInfo.insertSimple", userAccountBo);
					if(isOk(resultMap)){
						ProCacheUtil.addCache(CacheName.USERACCOUNT_ID, userAccountBo.getUser_id().toString() ,userAccountBo);
					}
					
				}
			}
		} catch (Exception e) {
			exception(e,resultMap, userInfoBO);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 删除用户
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.DELETE, value = RequestURL.User.USER_INFO)
	public ModelAndView delete(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestParam Integer id ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			if(ObjectUtil.isEmpty(id)){
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.PARAM_ERROR);
			}else{
				UserInfoBO obj = new UserInfoBO();
				if(id != getUserInfoByUserKey(userKey).getId()+0){
					if( verifyUserRole(userKey,Code.UserType.SUPER) ){
						;
					}else{
						obj.setAid(getUserInfoByUserKey(userKey).getId());					
					}
					obj.setId(id);
					obj.setDelete_flag(Constants.DELETE.YES);
					resultMap = service.update("UserInfo.update", obj) ;
					if(isOk(resultMap)){
						// 清空缓存信息
						UserInfoBO tmp =new UserInfoBO();
						tmp.setId(id);
						tmp.setDelete_flag(Constants.DELETE.YES);
						resultMap = service.selectOne("UserInfo.selectOne", tmp );
						tmp = getData(resultMap);
						ProCacheUtil.removeCache(CacheName.USERINFO, tmp.getUser_key());
						
						// 删除跟用户关联的场景信息
						IotSceneUserRelationBO userRelation = new IotSceneUserRelationBO();
						userRelation.setUser_id(id);
						service.delete("IotSceneUserRelation.deleteUserRelation", userRelation) ;
					}
				}else{
					putStatusCode(resultMap, Code.ResponseCode.SystemCode.EXEC_FAIL);
				}
			}
		} catch (Exception e) {
			exception(e,resultMap, id);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 获取用户信息
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.GET, value = RequestURL.User.USER_INFO)
	public ModelAndView getOne(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestParam Integer id ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			if(ObjectUtil.isEmpty(id)){
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.PARAM_ERROR);
			}else{
				UserInfoBO obj = new UserInfoBO();
				if( verifyUserRole(userKey,Code.UserType.SUPER) ){
					;
				}else{
//					obj.setAid(getUserInfoByUserKey(userKey).getId());
				}
				obj.setDelete_flag(Constants.DELETE.NO);
				obj.setId(id);
				resultMap = service.selectOne("UserInfo.selectOne", obj) ;		
			}
		} catch (Exception e) {
			exception(e,resultMap, id);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 关联自由账户为普通用户
	 * @param response
	 * @param userKey
	 * @param userName
	 * @return
	 */
	@RequestMapping(method = RequestMethod.PUT, value = RequestURL.User.BIND_SUB_ACCOUNT)
	public ModelAndView UserSettingSub(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey , @RequestParam String userName ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			if(ObjectUtil.isEmpty(userName)){
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.PARAM_ERROR);
			}else{
				UserInfoBO userInfo = new UserInfoBO() ;
				userInfo.setDelete_flag(Constants.DELETE.NO);
				userInfo.setName(userName);
				resultMap = service.selectOne("UserInfo.selectOne", userInfo ) ;
				userInfo = getData(resultMap) ;
				if(isOk(resultMap) && (userInfo.getAid()== null ||userInfo.getAid() == -1   )) {
					UserInfoBO mainUserInfo = ProCacheUtil.getCache(CacheName.USERINFO, userKey) ;
					if(ObjectUtil.isNotEmpty(mainUserInfo)){
						// 更新
						UserInfoBO user= new UserInfoBO() ;
						user.setId(userInfo.getId());
						user.setAid( mainUserInfo.getId());
						service.update("UserInfo.updateAid", user ) ;
					}
				}else{
					putStatusCode(resultMap, Code.ResponseCode.SystemCode.PARAM_ERROR);
				}
			}
		} catch (Exception e) {
			exception(e,resultMap, userName);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 发送验证码信息
	 */
	@RequestMapping(method = RequestMethod.GET, value = RequestURL.User.ACCOUNT_SECURITY_CODE)
	public ModelAndView getSecurityCode(HttpServletRequest req, HttpServletResponse resp,
			@PathVariable String phone ,@RequestParam String code , @RequestParam(required=false) Integer type ){
		Map<String, Object> resultMap = getResultMap();
		try {
			// 这边判断验证码有没有填写成功
			String scode = (String) req.getSession().getAttribute("validate_code");
		    Long ltime =  (Long) req.getSession().getAttribute("validate_code_time");
		    if(ObjectUtil.isEmpty(scode)){
		    	putStatusCode(resultMap, Code.ResponseCode.SystemCode.CODE_TIME_ERROR);
		    }else{
		    	if( ! scode.equalsIgnoreCase(code) ){
		    		putStatusCode(resultMap, Code.ResponseCode.SystemCode.CODE_ERROR);
		    	}
		    	if(  ltime + 2*60*1000 <= new Date().getTime()){
		    		putStatusCode(resultMap, Code.ResponseCode.SystemCode.CODE_TIME_ERROR);
		    	}		    	
		    }
		    if(isOk(resultMap)){
		    	req.getSession().removeAttribute("validate_code");
			    req.getSession().removeAttribute("validate_code_time");
		    	
		    	Integer num = ProCacheUtil.getCache(CacheName.USER_SMS, phone) ;
		    	if(ObjectUtil.isNotEmpty(num)){
		    		if( num > 5){
		    			// 验证码超过数量
		    			putStatusCode(resultMap, Code.ResponseCode.SystemCode.VALIDATER_ALLER);
		    			return getModelAndView(resp, resultMap);
		    		}
		    		ProCacheUtil.addCache(CacheName.USER_SMS, phone, num+1);
		    	}else{
		    		ProCacheUtil.addCache(CacheName.USER_SMS, phone, 1 );
		    	}
		    	// ---
		    	String gcode = ObjectUtil.getSixRandomCode();
		    	
		    	// 设置到缓存中，过期时间暂不设置
		    	ProCacheUtil.addCache(CacheName.USER_SMS, phone+"_code", gcode);
		    	
		    	//
		    	AliyunParamBO aliyunParamBo = new AliyunParamBO();
		    	aliyunParamBo.setSignaName(ProConfig.AliyunShortMessage.SIGNATURE);
		    	aliyunParamBo.setPhonenumber(phone);
		    	if(ObjectUtil.isNotEmpty(type) && type ==1){
		    		aliyunParamBo.setTemplateCode(ProConfig.AliyunShortMessage.SMS_TEMPLATE_CODE);		    		
		    	}else{
		    		aliyunParamBo.setTemplateCode(ProConfig.AliyunShortMessage.SMS_LOGIN_TEMPLATE_CODE);	
		    	}
		    	Map<String,String> map = new HashedMap();
		    	map.put("code", gcode);
		    	aliyunParamBo.setTemplateParam( JSON.toJSONString(map));
		    	AliyunSmsAndVoiceUtil.sendSms(aliyunParamBo);
		    }
		} catch (Exception e) {
			exception(e,resultMap, phone);
		}
		return getModelAndView(resp, resultMap);
	}
	
	@RequestMapping(method = RequestMethod.GET, value = "/get/validate/code")
    public ModelAndView getValidateCode(HttpServletRequest req, HttpServletResponse resp){
		Map<String, Object> resultMap = getResultMap();
		try {
			 // randomCode用于保存随机产生的验证码，以便用户登录后进行验证。
			Random random = new Random();
	        StringBuffer randomCode = new StringBuffer();
	        int red = random.nextInt(255) , green = random.nextInt(255), blue = random.nextInt(255);
	        char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 
	        		'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
		            'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
	        // 随机产生codeCount数字的验证码。
	        for (int i = 0; i < 4; i++) {
	            // 得到随机产生的验证码数字。
	            String code = String.valueOf(codeSequence[random.nextInt(codeSequence.length-1)]);
	            // 将产生的四个随机数组合在一起。
	            randomCode.append(code);
	        }
	        // 将四位数字的验证码保存到Session中。
	        req.getSession().setAttribute("validate_code", randomCode.toString());
	        req.getSession().setAttribute("validate_code_time", System.currentTimeMillis());
	        
	        putData(resultMap,randomCode.toString() );
	        
		} catch (Exception e) {
			exception(e,resultMap);
		}
		return getModelAndView(resp, resultMap);
	}
	
	/**
	 * 图片验证码生成
	 * @param req
	 * @param resp
	 * @throws IOException
	 * <img alt="验证码" title="点击更新" id="validate-code" src="<%=basePath%>/service/validate/code" >
	 */
	@RequestMapping(method = RequestMethod.GET, value = "/validate/code")
    public void getCode(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		int width = 90;			// 定义图片的width
	    int height = 38;		// 定义图片的height
	    int codeCount = 4;		// 定义图片上显示验证码的个数
	    int xx = 15;
	    int fontHeight = 22;
	    int codeY = 28;
	    char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
	            'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
		
        // 定义图像buffer
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics gd = buffImg.getGraphics();
        // 创建一个随机数生成器类
        Random random = new Random();
        // 将图像填充为白色
        gd.setColor(Color.WHITE);
        gd.fillRect(0, 0, width, height);
        // 创建字体，字体的大小应该根据图片的高度来定。
        Font font = new Font("Fixedsys", Font.BOLD, fontHeight);
        // 设置字体。
        gd.setFont(font);
        // 画边框。
        gd.setColor(Color.BLACK);
        gd.drawRect(0, 0, width - 1, height - 1);
        // 随机产生20条干扰线，使图象中的认证码不易被其它程序探测到。
        gd.setColor(Color.BLACK);
        for (int i = 0; i < 20; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            gd.drawLine(x, y, x + xl, y + yl);
        }
        // randomCode用于保存随机产生的验证码，以便用户登录后进行验证。
        StringBuffer randomCode = new StringBuffer();
        int red = random.nextInt(255) , green = random.nextInt(255), blue = random.nextInt(255);
        // 随机产生codeCount数字的验证码。
        for (int i = 0; i < codeCount; i++) {
            // 得到随机产生的验证码数字。
            String code = String.valueOf(codeSequence[random.nextInt(codeSequence.length-1)]);
            // 产生随机的颜色分量来构造颜色值，这样输出的每位数字的颜色值都将不同。
            // 用随机产生的颜色将验证码绘制到图像中。
            gd.setColor(new Color(red, green, blue));
            gd.drawString(code, (i + 1) * xx, codeY);
            // 将产生的四个随机数组合在一起。
            randomCode.append(code);
        }
        // 将四位数字的验证码保存到Session中。
        req.getSession().setAttribute("validate_code", randomCode.toString());
        req.getSession().setAttribute("validate_code_time", System.currentTimeMillis());
        // 禁止图像缓存。
        resp.setHeader("Pragma", "no-cache");
        resp.setHeader("Cache-Control", "no-cache");
        resp.setDateHeader("Expires", 0);
        resp.setContentType("image/jpeg");
        // 将图像输出到Servlet输出流中。
        ServletOutputStream sos = resp.getOutputStream();
        ImageIO.write(buffImg, "jpeg", sos);
        sos.close();
    }
	
	
}
